package top.jacktgq.sxt.bio.ChatRoom.version5;

import top.jacktgq.sxt.bio.ChatRoom.version5.utils.ResourceUtils;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @Author CandyWall
 * @Date 2019/10/22--18:45
 * @Description 在线聊天室：服务器
 *              目标：封装出一个类使用多线程实现一个服务器可以正常收发多条消息
 */
public class ChatServer {
    public static void main(String[] args) throws IOException {
        System.out.println("服务器启动...");
        //1、指定端口 使用ServerSocket创建服务器
        ServerSocket serverSocket = new ServerSocket(8888);
        Boolean isUsedForMultiClients = true;   //是否服务于多个客户端
        while (isUsedForMultiClients) {
            //2、阻塞式等待连接accept
            Socket server = serverSocket.accept();
            System.out.println("一个客户端建立了连接");
            new Thread(new Channel(server)).start();
        }
        serverSocket.close();
    }

    //一个客户端代表一个Channel
    static class Channel implements Runnable {
        private DataInputStream dis = null;
        private DataOutputStream dos = null;
        private Socket server;
        private boolean isRunning;

        public Channel(Socket server) {
            //3、接收客户端发送的消息
            this.server = server;
            try {
                dis = new DataInputStream(server.getInputStream());
                dos = new DataOutputStream(server.getOutputStream());
                isRunning = true;
            } catch (IOException e) {
                e.printStackTrace();
                //只要在获取连接的过程中发生异常，就释放资源，断开连接
                release();
            }
        }

        //接收消息
        private String receive() {
            String msg = null;
            try {
                msg = dis.readUTF();
            } catch (IOException e) {
                e.printStackTrace();
                release();
            }
            return msg;
        }

        //发送消息
        private void send(String msg) {
            try {
                dos.writeUTF(msg);
                dos.flush();
            } catch (IOException e) {
                e.printStackTrace();
                release();
            }
        }

        //释放资源
        private void release() {
            //停止本次与客户端的通信（接收消息和发送消息）
            this.isRunning = false;
            ResourceUtils.close(dis, dos, server);
        }

        @Override
        public void run() {
            while (isRunning) {
                String content = receive();
                //过滤掉客户端发来的空消息
                if (!"".equals(content)) {
                    System.out.println("客户端发来：" +  content);
                    //4、返回消息
                    send(content);
                }
            }

            //释放资源
            release();
        }
    }

}
